#include "opengl_context_pool_win32.h"
#include "opengl_context_win32.h"
#include "exceptions.h"
#include <gl/gl.h>

using namespace krryn::system;
using namespace krryn::core;

opengl_context_pool_win32::opengl_context_pool_win32(HWND hWnd, long a_NumberOfContexts)
: m_Current(0){
	this->hWnd = hWnd;

	m_PrimaryContext = new opengl_context_win32(hWnd);

	for(long i = 0; i < a_NumberOfContexts; i++){
		m_Contexts.push_back(new opengl_context_win32(hWnd, m_PrimaryContext));
	}

	// this should be called after the constructor or specifically; 
	// wglMakeCurrent should be called after wglShareLists for the 
	// resources that share lists. If this is not done this way,
	// the opengl might display garbage the first frame.
	m_PrimaryContext->attach();
}

opengl_context_pool_win32::~opengl_context_pool_win32(){
	// detach opengl contexts before deleting them
	if(wglGetCurrentContext() != NULL)
		m_PrimaryContext->detach();

	for(size_t i = 0; i < m_Contexts.size(); i++){
		m_Contexts[i]->detach();
		delete m_Contexts[i];
		m_Contexts[i] = 0;
	}

	delete m_PrimaryContext;
	m_PrimaryContext = 0;
}

void opengl_context_pool_win32::attach_context(){
	locker<mutex> l_Section(m_Guard);

	HGLRC hRC = wglGetCurrentContext();

	if(hRC == NULL){
		if(m_Current < m_Contexts.size()){
			opengl_context_win32 *l_Context = m_Contexts[m_Current];
			l_Context->attach();

			m_Current++;
		}else{
			throw renderer_exception("Out of opengl contexts");
		}
	}
}

void opengl_context_pool_win32::swap_buffers(){
	m_PrimaryContext->swap_buffers();
}